home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / Z4Z4EX.C < prev    next >
C/C++ Source or Header  |  1995-07-27  |  9KB  |  310 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    Z4Z4ex.c
  5. //   Title:    ZIP+4 Engine
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //
  24. //    This module contains the expander for the ZIP+4 file.
  25. //    This module should not use any global variables since it must be 
  26. //    re-entrant.
  27. //
  28. //    The code in this module should be written entirely in C. 
  29. //    Do not use any C++ constructs.
  30. //
  31. //    This module is portable to:
  32. //        DOS 3.X+
  33. //        MS Windows 3.X+
  34. //        OS/2 2.X+
  35. //        OS/2 2.0 PM
  36. //        SCO UNIX.
  37. //
  38. //    The following compilers are supported:
  39. //        MSC 6.0A
  40. //        MSC/C++ 7.0
  41. //        Borland C++ 3.1 for DOS
  42. //        Borland C++ 1.0 for OS/2 2.X
  43. //        SCO UNIX cc
  44. //
  45. //----------------------------------------------------------------------------
  46. #include <z4.h>
  47.  
  48.  
  49. //----------------------------------------------------------------------------
  50. //   Description:    Read a compressed record from the output buffer.
  51. //    Parameters: pblk        Decoder data structure
  52. //                        pz4        Expanded record
  53. //       Returns:    TRUE if successful. FALSE if not more records found to 
  54. //                        decode.
  55. //----------------------------------------------------------------------------
  56. BOOL FN_E Z4Z4Expand(PZ4_Z4_BLK pblk, PZ4_Z4 pz4)
  57. {
  58.     PBYTE pb;
  59.     SIZET cb;
  60.     BYTE b, b2 = 0;
  61.     USHORT us1;
  62.     SIZET cString;
  63.     PCSZ pcszNumeric;
  64.  
  65.     //
  66.     //    Set up
  67.     //
  68.     Assert(pblk && pz4);
  69.     if (pblk->cbNext >= pblk->cb - 1)    // Need at least 2 bytes for a record
  70.         return FALSE;
  71.     Assert(pblk->cbNext <= pblk->cb);    // THIS SHOULD NOT HAPPEN
  72.     pb = pblk->pb + pblk->cbNext;            
  73.     if (*(PUSHORT)pb == 0)                    // Block not full, but no more records
  74.         {
  75.         pblk->cbNext = pblk->cb;
  76.         return FALSE;
  77.         }
  78.     //
  79.     //    Decode this record
  80.     //
  81.     us1 = *(PUSHORT)pb;                        // Read bit flags
  82.     pb += sizeof(USHORT);
  83.     if (us1 & Z4_BYTE_FOLLOWS)
  84.         b2 = *pb++;
  85.  
  86.     if (us1 & Z41_UNIT_REC_TYPE)
  87.         {
  88.         b = *pb++;
  89.         pblk->z4.rectype = (Z4_TYPE)(b & 0x07);
  90.         pblk->z4.unit = (Z4_UNIT)(b >> 3);
  91.         }
  92.     if (us1 & Z41_DIR)
  93.         {
  94.         b = *pb++;
  95.         pblk->z4.postdir = (Z4_DIR)(b & 0x0F);
  96.         pblk->z4.predir = (Z4_DIR)(b >> 4);
  97.         }
  98.     if (us1 & Z41_CODES)
  99.         {
  100.         b = *pb++;
  101.         pblk->z4.alt = (Z4_ALT)(b & 0x03);
  102.         pblk->z4.pricode = (Z4_CODE)((b >> 2) & 0x03);
  103.         pblk->z4.seccode = (Z4_CODE)((b >> 4) & 0x03);
  104.         pblk->z4.fOrdinal = (BOOL)(((b >> 6) & 0x01) != 0);
  105.         }
  106.     if (us1 & Z41_PRI_LO)
  107.         {
  108.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szPriLo);
  109.         pb += cString;
  110.         }
  111.     if (us1 & Z41_PRI_DELTA_LO)
  112.         {
  113.         BYTE bDelta = *pb++;
  114.         LONG lPriLo = atol(pblk->z4.szPriLo);
  115.         sprintf(pblk->z4.szPriLo, "%ld", (LONG)(lPriLo + (LONG)bDelta));
  116.         }
  117.     if (us1 & Z41_PRI_HI)            
  118.         {
  119.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szPriHi);
  120.         pb += cString;
  121.         }
  122.     if (us1 & Z41_PRI_DELTA_HI)
  123.         {
  124.         BYTE bDelta = *pb++;
  125.         LONG lPriLo = atol(pblk->z4.szPriLo);
  126.         sprintf(pblk->z4.szPriHi, "%ld", (LONG)(lPriLo + (LONG)bDelta));
  127.         }
  128.     if (us1 & Z41_SEC_LO)
  129.         {
  130.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szSecLo);
  131.         pb += cString;
  132.         }
  133.     if (us1 & Z41_SEC_HI)            
  134.         {
  135.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szSecHi);
  136.         pb += cString;
  137.         }
  138.     if (us1 & Z41_PRI_NAME)
  139.         {
  140.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szPriName);
  141.         pb += cString;
  142.         }
  143.     if (us1 & Z41_ADDON_LO)
  144.         {
  145.         strb2a(pb, MAX_ADDON_BCD, pblk->z4.szAddonLo, MAX_ADDON, TRUE);
  146.         pb += MAX_ADDON_BCD;
  147.         }
  148.     if (us1 & Z41_ADDON_HI)
  149.         {
  150.         strb2a(pb, MAX_ADDON_BCD, pblk->z4.szAddonHi, MAX_ADDON, TRUE);
  151.         pb += MAX_ADDON_BCD;
  152.         }
  153.     if (us1 & Z41_SUFFIX1)
  154.         {
  155.         pblk->z4.suffix1 = (Z4_SUFFIX)*pb++;
  156.         }
  157.     if (us1 & Z41_SUFFIX2)
  158.         {
  159.         pblk->z4.suffix2 = (Z4_SUFFIX)*pb++;
  160.         }
  161.     if (b2 & Z42_SEC_NAME)
  162.         {
  163.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szSecName);
  164.         pb += cString;
  165.         }
  166.     if (b2 & Z42_ZIP5)
  167.         {
  168.         strb2a(pb, MAX_ZIP5_BCD, pblk->z4.szZip5, MAX_ZIP5, TRUE);
  169.         pb += MAX_ZIP5_BCD;
  170.         }
  171.     if (b2 & Z42_CRIS)
  172.         {
  173.         StringDecode(pblk->pcache, pb, &cString, pblk->z4.szCris);
  174.         pb += cString;
  175.         }
  176.     if (b2 & Z42_LAST_LINE)
  177.         {
  178.         strb2a(pb, MAX_LAST_LINE_BCD, pblk->z4.szLastLine, MAX_LAST_LINE, TRUE);
  179.         pb += MAX_LAST_LINE_BCD;
  180.         }
  181.     if (b2 & Z42_FINANCE)
  182.         {
  183.         strb2a(pb, MAX_FINANCE_BCD, pblk->z4.szFinance, MAX_FINANCE, TRUE);
  184.         pb += MAX_FINANCE_BCD;
  185.         }
  186.     //
  187.     //    Handle special bits
  188.     //
  189.     if (us1 & Z41_ADDON_LO_HI)
  190.         strcpy(pblk->z4.szAddonHi,pblk->z4.szAddonLo);
  191.     if (b2 & Z42_PRI_LO_HI)
  192.         strcpy(pblk->z4.szPriHi,pblk->z4.szPriLo);
  193.     if (b2 & Z42_SEC_LO_HI)
  194.         strcpy(pblk->z4.szSecHi,pblk->z4.szSecLo);
  195.     if (b2 & Z42_SEC_NAME_BLANK)
  196.         pblk->z4.szSecName[0] = '\0';
  197.  
  198.     //
  199.     //    Do some cleanup work
  200.     //
  201.     if (strcmp(pblk->z4.szAddonHi, "0000") == 0)
  202.         strcpy(pblk->z4.szAddonHi, "ND");
  203.     if (strcmp(pblk->z4.szAddonLo, "0000") == 0)
  204.         strcpy(pblk->z4.szAddonLo, "ND");
  205.     if (pblk->z4.szSecLo[0] == '-')
  206.         pblk->z4.szSecLo[0] = '0';
  207.     if (pblk->z4.szSecHi[0] == '-')
  208.         pblk->z4.szSecHi[0] = '0';
  209.     if (pblk->z4.szPriLo[0] == '-')
  210.         pblk->z4.szPriLo[0] = '0';
  211.     if (pblk->z4.szPriHi[0] == '-')
  212.         pblk->z4.szPriHi[0] = '0';
  213.  
  214.     switch (pblk->z4.rectype)
  215.         {
  216.         case Z4_TYPE_POB:
  217.             strcpy(pblk->z4.szPriName, "PO BOX");
  218.             break;
  219.  
  220.         case Z4_TYPE_GD:
  221.             strcpy(pblk->z4.szPriName, "GENERAL DELIVERY");
  222.             break;
  223.  
  224.         case Z4_TYPE_PM:
  225.             strcpy(pblk->z4.szPriName, "POSTMASTER");
  226.             break;
  227.         }
  228.                                                     // Check if primary name of record is all numeric
  229.     pblk->z4.fNumeric = TRUE;
  230.     pcszNumeric = pblk->z4.szPriName;
  231.     for (; pcszNumeric[0]; ++pcszNumeric)
  232.         if (!isdigit(pcszNumeric[0]))
  233.             {
  234.             pblk->z4.fNumeric = FALSE;
  235.             break;
  236.             }
  237.     //
  238.     //    Done, clean up
  239.     //
  240.     cb = (SIZET)(pb - pblk->pb);
  241.     Assert(cb <= pblk->cb);
  242.     pblk->cbNext = cb;
  243.     *pz4 = pblk->z4;                            // Return a copy of the current record
  244.     return TRUE;
  245. }
  246.  
  247.  
  248. //----------------------------------------------------------------------------
  249. //   Description:    Initialize city/state expander
  250. //    Parameters:    pblk            City/state decoder data structure
  251. //       Returns:    TRUE if successful.
  252. //----------------------------------------------------------------------------
  253. BOOL FN_E Z4Z4ExpandInitialize(PZ4_Z4_BLK pblk)
  254. {
  255.     Assert(pblk);
  256.     memset(pblk, 0, sizeof(Z4_Z4_BLK));
  257.     pblk->pcache = StringCreate(Z4_Z4_WORD_CACHE, 0);
  258.     if (pblk->pcache == NULL)
  259.         return FALSE;
  260.     return TRUE;
  261. }
  262.  
  263.  
  264. //----------------------------------------------------------------------------
  265. //   Description:    Reset expander to decode another block of data
  266. //    Parameters:    pblk            Decoder data structure
  267. //                        pb                Buffer containing compressed data.
  268. //                        cb                Size of buffer.
  269. //       Returns:    TRUE if successful.
  270. //----------------------------------------------------------------------------
  271. BOOL FN_E Z4Z4ExpandReset(PZ4_Z4_BLK pblk, PBYTE pb, SIZET cb)
  272. {
  273.     Assert(pblk);
  274.     StringReset(pblk->pcache);
  275.     memset(&pblk->z4, 0, sizeof(Z4_Z4));
  276.  
  277.     pblk->z4.seccode = Z4_BOTH;            // Set default record characteristics
  278.     pblk->z4.pricode = Z4_BOTH;
  279.     pblk->z4.rectype = Z4_TYPE_ST;
  280.     pblk->z4.predir = Z4_DIR_BLANK;
  281.     pblk->z4.postdir = Z4_DIR_BLANK;
  282.     pblk->z4.unit = Z4_UNIT_BLANK;
  283.     pblk->z4.alt = Z4_ALT_B;
  284.     pblk->z4.suffix1 = 0;
  285.     pblk->z4.suffix2 = 0;
  286.  
  287.     pblk->pb = pb;                                // Set decoding pointers
  288.     pblk->cb = cb;
  289.     pblk->cbNext = 0;
  290.     return TRUE;
  291. }
  292.  
  293.  
  294. //----------------------------------------------------------------------------
  295. //   Description:    Terminate city/state expander.
  296. //    Parameters:    pblk            City/state decoder data structure
  297. //       Returns:    TRUE if successful.
  298. //----------------------------------------------------------------------------
  299. BOOL FN_E Z4Z4ExpandTerminate(PZ4_Z4_BLK pblk)
  300. {
  301.     Assert(pblk);
  302.     if (pblk->pcache)                            // Close word cache
  303.         WordDestroy(pblk->pcache);
  304.     memset(pblk, 0, sizeof(Z4_Z4_BLK));
  305.     return TRUE;
  306. }
  307. //----------------------------------------------------------------------------
  308. //------------------------------- End of File --------------------------------
  309. //----------------------------------------------------------------------------
  310.